using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using LispLib;

namespace GeneticAlgorithm.CP3.BitString
{
    class Individual : Individual<int[], Interpreter.Pair>
    {
        /// <summary>
        /// I need an enum to convert bits into lisp commands.  This one represents the decoding for a binary bit string.
        /// The array right after it hold the conversions.  Eventually, I'd like to take this hardcoding out so I can 
        /// simply refer to text files, but for now, this solution will do.
        /// </summary>
        /// <returns></returns>
        /// 

        //Change CMDS_INDEX to change the value of the first.  Do this since it is used elsewhere.
        private enum Cmds
        {
            zero,

            one,

            two,

            three,

            four,

            five,

            six,

            seven,

            eight,

            nine,

            closePar,

            openPar,

            add,

            subtract,

            divide,

            multiply

            //There's always room for more.  When the hardcoding is taken out, we can create a series of text files
            //that represent the different things our sub-programming language (because that's what it is) can do
        }//enum Cmds


        //and the values thus taken:
        private string[] cmdVals = new string[] { "time ","1 ","2 ","3 ","4 ","5 ","6 ","7 ","8 ","9 ",
                                          "(", ")", "+ ", "- ", "* ", "* " };
        

        public Individual(int[] genotype, params Individual<int[], Interpreter.Pair>[] parents)
            : base(genotype, parents)
        {
        }

        /// <summary>
        /// Map bit string to strings
        /// </summary>
        /// <param name="genotype"></param>
        /// <returns></returns>
        public override Interpreter.Pair GeneticMapping(int[] genotype)
        {
            string lispLine = null; //

            //go through, and translate each into a String, then concatenate the String and, I dunno, return it?
            for (int x = 0; x < genotype.Length; x++)
            {
                //translate the element to a string and concatenate it into a string
                lispLine += decode(genotype[x]);

            }//for

            // parse string to parse tree
            //Interpreter i = new Interpreter();
            int pos = 0;
            return Interpreter.ReadOneExpr(lispLine, ref pos, lispLine.Length) as Interpreter.Pair;
        }

        /// <summary>
        /// Decode an int into a lisp command.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private String decode(int x)
        {

            string lispCmd = "@______:-(_____@invalid value@______:-(_____@";


       
            try
            {
                lispCmd = cmdVals[x];
            }
            catch (Exception e)
            {

                //
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("ERROR ERROR ERROR ERROR ERROR " + x);
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                //the above is for debugging purposes.  I need to figure out how to make this code compile with or without
                //debugging code at will.
                Console.WriteLine(e);
            }

            return lispCmd;

        }//decode


    }
}


/* Maybe not necessary, but let's keep it in scrap:
          /// <summary>
        /// Returns a random decoded value from the the integers in the enum.
        /// </summary>
        /// <returns></returns>
        public string replaceInt()
        {
            int newVal = randGen.Next(0, 11);
            return decode[newVal];
        }

        //second verse, similar to the first
        public string replaceFunction()
        {
            int newVal = randGen.Next(13, 17);
            return decode[newVal];
        }
*/
